<!--
@license
Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->

<link rel="import" href="../bower_components/plugin-element/plugin-element.html">
<link rel="import" href="../bower_components/plugin-element/plugin-message.html">
<link rel="import" href="../bower_components/plugin-element/plugin-payment.html">
<link rel="import" href="../bower_components/plugin-element/plugin-area-selector.html">
<link rel="import" href="../bower_components/app-route/app-route.html">
<link rel="import" href="../bower_components/iron-flex-layout/iron-flex-layout.html">
<link rel="import" href="../bower_components/paper-button/paper-button.html">
<link rel="import" href="../bower_components/paper-tabs/paper-tabs.html">
<link rel="import" href="../bower_components/paper-tabs/paper-tab.html">
<link rel="import" href="shop-button.html">
<link rel="import" href="shop-common-styles.html">
<link rel="import" href="shop-form-styles.html">
<link rel="import" href="shop-input.html">
<link rel="import" href="shop-select.html">
<link rel="import" href="shop-checkbox.html">

<dom-module id="shop-checkout">

    <template>
    <style include="shop-common-styles shop-button shop-form-styles shop-input shop-select shop-checkbox">

      .main-frame {
        transition: opacity 0.5s;
      }

      :host([waiting]) .main-frame {
        opacity: 0.1;
      }

      shop-input, shop-select {
        font-size: 16px;
      }

      shop-select {
        margin-bottom: 20px;
      }

      paper-spinner-lite {
        position: fixed;
        top: calc(50% - 14px);
        left: calc(50% - 14px);
      }

      .billing-address-picker {
        margin: 28px 0;
        height: 20px;
        @apply --layout-horizontal;
      }

      .billing-address-picker > label {
        margin-left: 12px;
      }

      .grid {
        margin-top: 40px;
        @apply --layout-horizontal;
      }

      .grid > section {
        @apply --layout-flex;
      }

      .grid > section:not(:first-child) {
        margin-left: 80px;
      }

      .row {
        @apply --layout-horizontal;
        @apply --layout-end;
      }

      .column {
        @apply --layout-vertical;
      }

      .row > .flex,
      .input-row > * {
        @apply --layout-flex;
      }

      .input-row > *:not(:first-child) {
        margin-left: 8px;
      }

      .shop-select-label {
        line-height: 20px;
      }

      .order-summary-row {
        line-height: 24px;
      }

      .total-row {
        font-weight: 500;
        margin: 30px 0;
      }

      @media (max-width: 767px) {

        .grid {
          display: block;
          margin-top: 0;
        }

        .grid > section:not(:first-child) {
          margin-left: 0;
        }

      }
        .actions{
            display: flex;
            position: fixed;
            bottom: 0px;
            width: 100%;
            left: 0px;
        }
        .actions>*{
            flex: 1;
            width: 100%;
        }
        .actions shop-button{
            width: 100%;
        }
        .actions input{
            border: none;
            width:100%;
            background-color: #172c50;
            color: #fff;
            box-sizing: border-box;
            padding: 20px;
        }
        .actions input.plugin_button{
            background-color: #336699;
        }
        paper-tabs {
            --paper-tabs-selection-bar-color:#000;
            margin-bottom: 10px;
        }
        hr{
                height: 5px;
                background: #eee;
                border: none;
                margin: 10px 0px;
                padding: 0px;
        }
    </style>
    <plugin-xhr id="xhr_plugin_list_by_category" url="[[app.apiHost]]/plugin.list.by.category" response="{{plugins}}" response-property="result"></plugin-xhr>    
    <plugin-xhr id="xhr_express_list" url="[[app.apiHost]]/express.list.area" response="{{expresses}}" response-property="result"></plugin-xhr>    
    <plugin-xhr id="xhr_express_freight_count" url="[[app.apiHost]]/express.freight.count" response="{{freight}}"></plugin-xhr>
    <plugin-xhr id="xhr_trade_create" url="[[app.apiHost]]/trade.create" response="{{trade}}"></plugin-xhr>
    <plugin-xhr id="xhr_discount_list_filter" url="[[app.apiHost]]/discount.list.filter"></plugin-xhr>
    <plugin-xhr id="xhr_my_coupon_available" url="[[app.apiHost]]/my.coupon.available"></plugin-xhr>
    <plugin-xhr id="xhr_open_page" url="[[app.apiHost]]/wx.app.call?name=openPage"></plugin-xhr>
    <plugin-message id="msg"></plugin-message>
    <div class="main-frame">
      <iron-pages id="pages" selected="[[state]]" attr-for-selected="state">
        <div state="init">
          <iron-form id="checkoutForm"
              on-iron-form-response="_didReceiveResponse"
              on-iron-form-presubmit="_willSendRequest">
            <form method="post" action="data/sample_success_response.json">

              <div class="subsection" visible$="[[!_hasItems]]">
                <p class="empty-cart">当前购物车是空的.</p>
              </div>

              <header class="subsection" visible$="[[_hasItems]]">
                <h1>请确认您的订单</h1>
                <span>填写配送信息并完成支付</span>
              </header>
              <div class="subsection grid" visible$="[[_hasItems]]">
                <paper-tabs id="nav" selected="{{takeBySelf}}" hide-scroll-buttons>
                    <paper-tab>送货上门</paper-tab>
                    <paper-tab>到店自取</paper-tab>
                </paper-tabs>
                <section>
                <div hidden$="[[takeBySelf]]">
                    <plugin-area-selector id="areaSelector" value="{{area}}"></plugin-area-selector>
                  <div class="row input-row">
                    <shop-input>
                      <input type="text" id="shipAddress" name="shipAddress" pattern=".{5,}"
                          placeholder="街道地址" required
                          aria-labelledby="shipAddressLabel shipAddressHeading">
                      <shop-md-decorator error-message="请填写正确的街道地址" aria-hidden="true">
                        <label id="shipAddressLabel">街道地址</label>
                        <shop-underline></shop-underline>
                      </shop-md-decorator>
                    </shop-input>
                  </div>
                  <div class="row input-row">
                    <p>
                        <shop-input>
                          <input type="text" id="realname" name="realname"
                              placeholder="联系人姓名" required
                              aria-labelledby="realnameLabel contactHeading">
                          <shop-md-decorator error-message="请输入正确的联系人姓名" aria-hidden="true">
                            <label id="realnameLabel">联系人姓名</label>
                            <shop-underline></shop-underline>
                          </shop-md-decorator>
                        </shop-input>  
                    </p>
                    <p>
                        <shop-input>
                          <input type="tel" id="telephone" name="telephone" pattern="\d{10,}"
                              placeholder="联系电话" required
                              aria-labelledby="telephoneLabel contactHeading">
                          <shop-md-decorator error-message="请输入正确的电话号码" aria-hidden="true">
                            <label id="telephoneLabel">电话号码</label>
                            <shop-underline></shop-underline>
                          </shop-md-decorator>
                        </shop-input>
                    </p>
                  </div>
                
                
                <template is="dom-if" if="[[area]]">
                    <div class="column">
                    <template is="dom-if" if="[[!expressAvailable]]">
                       <p>该地区物流无法送达</p>
                    </template>
                    <template is="dom-if" if="[[expressAvailable]]">
                    <label id="expressLabel" class="shop-select-label">快递</label>
                    <shop-select>
                      <select id="express" name="express" required$="[[!takeBySelf]]"
                          aria-labelledby="expressLabel shipAddressHeading" value="[[expressValue]]" on-change="_expressSelected">
                          <option value="">请选择快递</option>
                          <template is="dom-repeat" items="[[expresses]]" as="express">
                              <option value="[[express.id]]">[[express.name]]</option>
                          </template>
                      </select>
                      <shop-md-decorator aria-hidden="true">
                        <shop-underline></shop-underline>
                      </shop-md-decorator>
                    </shop-select>
                    </template>
                  </div>
                </template>
                
                </div>
                  <div hidden$="[[!takeBySelf]]">
                    <p style="text-align: center;padding:20px">付款成功后凭提货二维码自行向店主提货。</p>
                  </div>
                </section>
                  <hr/>
                <section>
                  <h2>订单信息</h2>
    <template is="dom-if" if="[[!single]]">
        <dom-repeat items="[[cart]]" as="entry">
            <template>
              <div class="row order-summary-row">
                <div class="flex">[[entry.item.title]]([[_skuDisplay(entry.sku)]] x [[entry.quantity]])</div>
                <div>[[_getEntryTotal(entry)]]</div>
              </div>
            </template>
        </dom-repeat>
        <div class="row total-row">
            <div class="flex">货款总额</div>
            <div>[[_formatPrice(total)]]</div>
        </div>
    </template>
    <template is="dom-if" if="[[single]]">
        <div class="row order-summary-row">
            <div class="flex">[[singleItem.item.title]]([[_skuDisplay(singleItem.sku)]] x [[singleItem.quantity]])</div>
            <div>[[_getEntryTotal(singleItem)]]</div>
        </div>
    </template>
    <div class="row order-summary-row">
        <div class="flex">运费</div>
        <div>[[_formatPrice(freight)]]</div>
    </div>
    <template is="dom-if" if="[[discount]]">
        <div class="row order-summary-row">
            <div class="flex">折扣【[[discount.name]]】</div>
            <div>[[_discountMoney(discount)]]</div>
        </div>
    </template>
    <template is="dom-if" if="[[couponRecord]]">
        <div class="row order-summary-row">
            <div class="flex">优惠卷【[[couponRecord.coupon.money]]元优惠卷可用】</div>
            <div>[[_couponMoney(couponRecord.coupon)]]</div>
        </div>
    </template>
    <div class="row total-row">
        <div class="flex">实付总额</div>
        <div>[[_formatPrice(payAmount)]]</div>
    </div>
                    
    <div class="row total-row">
        <shop-input style="width:100%">
          <input type="text" id="customerRemarks" name="customerRemarks" placeholder="备注信息"
              aria-labelledby="customerRemarksLabel customerRemarksHeading">
          <shop-md-decorator error-message="请填写正确的备注信息" aria-hidden="true">
            <label id="customerRemarksLabel">备注信息</label>
            <shop-underline></shop-underline>
          </shop-md-decorator>
        </shop-input>
    </div>
    <div class="actions">
        <template is="dom-repeat" items="[[plugins]]" as="plugin">
            <shop-button>
                <input type="button" class="plugin_button" on-click="_submitByPlugin" value="[[plugin.display_name]]">
            </shop-button>
        </template>
        <div>
            <shop-button id="submitBox">
                <input type="button" id="submitButton" on-click="_submitByPayment" value="支付订单">
            </shop-button>
        </div>
    </div>
    </section>
    </div>
    </form>
    </iron-form>
    </div>
    
    <!-- Success message UI -->
    <header state="success">
        <h1>您的订单已创建</h1>
        <div hidden="[[paymented]]">
        <p>[[response.successMessage]]</p>
        <plugin-payment id="payment" hidden-success-message trade-id="[[trade.id]]" on-success="_paymentSuccess" on-fail="_paymentFail"></plugin-payment>
        </div>
        <div hidden="[[!paymented]]">
            <p>感谢您的惠顾！</p>
        </div>
        <shop-button responsive>
            <a href="/my-trade?id=[[trade.id]]">查看订单</a>
        </shop-button>
    </header>

    <!-- Error message UI -->
    <header state="error">
        <h1>无法处理订单</h1>
        <p id="errorMessage">[[response.errorMessage]]</p>
        <shop-button responsive>
            <template is="dom-if" if="[[single]]">
                <a href="/checkout?single=true">重试</a>
            </template>
            <template is="dom-if" if="[[!single]]">
                <a href="/checkout">重试</a>
            </template>
        </shop-button>
    </header>

    </iron-pages>

    </div>

    <!-- Handles the routing for the success and error subroutes -->
    <app-route active="{{routeActive}}" data="{{routeData}}" route="[[route]]" pattern="/:state">
    </app-route>

    <!-- Show spinner when waiting for the server to repond -->
    <paper-spinner-lite active="[[waiting]]" hidden style="display: none"></paper-spinner-lite>

    </template>

    <script>
        class ShopCheckout extends PluginElement {

            static get is() {
                return 'shop-checkout';
            }

            static get properties() {
                return {

                    /**
                     * The route for the state. e.g. `success` and `error` are mounted in the
                     * `checkout/` route.
                     */
                    route: {
                        type: Object,
                        notify: true
                    },
                    expressAvailable:Boolean,

                    /**
                     * The total price of the contents in the user's cart.
                     */
                    total:Number,
                    payAmount:Number,
                    freight:{
                        type:Number,
                        value:0,
                        observer:"_flushPayAmount"
                    },

                    /**
                     * The state of the form. Valid values are:
                     * `init`, `success` and `error`.
                     */
                    state: {
                        type: String,
                        value: 'init'
                    },

                    /**
                     * An array containing the items in the cart.
                     */
                    cart: Array,

                    /**
                     * The server's response.
                     */
                    response: Object,

                    /**
                     * If true, the user must enter a billing address.
                     */
                    takeBySelf: {
                        type: Boolean,
                        value: false,
                        observer:"_takeBySelfChanged"
                    },

                    /**
                     * If true, shop-checkout is currently visible on the screen.
                     */
                    visible: {
                        type: Boolean,
                        observer: '_visibleChanged'
                    },

                    /**
                     * True when waiting for the server to repond.
                     */
                    waiting: {
                        type: Boolean,
                        readOnly: true,
                        reflectToAttribute: true
                    },

                    /**
                     * True when waiting for the server to repond.
                     */
                    _hasItems: {
                        type: Boolean,
                        computed: '_computeHasItem(single,cart.length)'
                    },
                    area:{
                        type:Object,
                        observer:"_areaChanged"
                    },
                    trade:Object,
                    single:Boolean,
                    paymented:Boolean
                }
            }

            static get observers() {
                return [
                    '_updateState(routeActive, routeData)'
                ]
            }
            ready(){
                super.ready();
                this.$.shipAddress.value = this._cache("checkout.address");
                this.$.telephone.value = this._cache("checkout.telephone");
                this.$.realname.value = this._cache("checkout.realname");
                this.takeBySelf = this._cache("checkout.takeBySelf")=="true";
                let areaCache = this._cache("checkout.area");
                let pathArray = this._cache("checkout.pathArray");
                if(areaCache){
                    this.area = JSON.parse(areaCache);
                    if(pathArray){
                        this.$.areaSelector.pathArray = JSON.parse(pathArray);
                        this.$.areaSelector.path = this._cache("checkout.areaPath");
                        this._areaChanged();
                    }
                }
            }
            _paymentSuccess(e){
//                this._page("/my-trade?id="+this.trade.id);
                this.paymented = true;
            }
            _paymentFail(e){
                this.paymented = false;
            }
            _discountMoney(discount){
                return "-"+this._formatPrice(discount.rate/100*this.total);
            }
            _couponMoney(coupon){
                return "-"+this._formatPrice(coupon.money);
            }
            _flushPayAmount(){
                
                let money = this.single?this.singleItem.quantity * this.singleItem.item.price:this.total;
                let payAmount = money+(this.freight?this.freight:0);
                if(this.discount){
                    payAmount -= this.discount.rate/100*money;
                }
                if(this.couponRecord){
                    payAmount -= this.couponRecord.coupon.money;
                }
                this.payAmount = payAmount<this.freight?this.freight:payAmount;
            }
            _takeBySelfChanged(v){
                this.takeBySelf = Boolean(v);
                if(this.takeBySelf){
                   this.freight = 0;
                }else{
                    this._expressChanged();
                }
            }
            _areaChanged(e){
                let dom = this;
                if(this.area&&this.$.areaSelector.pathArray){
                    let rootArea = this.$.areaSelector.pathArray[0];
                    this.$.xhr_express_list.param("app_id",app.appId).param("area_id",rootArea?rootArea.id:area.id).callback(function(){
                        if(dom.expresses&&dom.expresses.length>0){
                           dom.expressAvailable = true;
                        }else{
                            dom.expressAvailable = false;
                        }
                    }).get();
                }else{
                    this.expressAvailable = false;
                }
            }
            _expressChanged(e){
                let products = new Object();
                if(this.single){
                    products[this.singleItem.item.name] = this.singleItem.quantity;
                }else{
                    this.cart.forEach(function(entry){
                        products[entry.item.name] = entry.quantity;
                    });
                }
                
                
                if(this.area&&!this._isEmpty(this.expressValue)){
                    let dom = this;
                    this.$.xhr_express_freight_count.param("express_id",this.expressValue).param("area_id",this.area.id).setBody(products).post();
                }else{
                    this.freight = 0;
                }
            }
            _expressSelected(e){
                this.expressValue = e.currentTarget.value;
            }
            _submit(e,successCallback) {
                let dom = this;
                if (this._validateForm()) {
                    // To send the form data to the server:
                    // 2) Remove the code below.
                    // 3) Uncomment `this.$.checkoutForm.submit()`.

                    this.$.checkoutForm.dispatchEvent(new CustomEvent('iron-form-presubmit', {
                        composed: true
                    }));
                    let products = new Array();
                    if(this.single){
                        products.push({amount:Number(this.singleItem.quantity),product:{id:Number(this.singleItem.item.name)},sku:{id:Number(this.singleItem.sku.id)}});
                    }else{
                        this.cart.forEach(function(entry){
                            products.push({amount:Number(entry.quantity),product:{id:Number(entry.item.name)},sku:{id:Number(entry.sku.id)}});
                        });
                    }
                    
                    this.$.xhr_trade_create
                    .param("discountId",this.discount?this.discount.id:"")
                    .param("couponRecordId",this.couponRecord?this.couponRecord.id:"")
                    .param("contacts",!this.takeBySelf?encodeURIComponent(this.$.realname.value):"")
                    .param("telephone",!this.takeBySelf?this.$.telephone.value:"")
                    .param("areaId",!this.takeBySelf?this.area.id:"")
                    .param("address",!this.takeBySelf?encodeURIComponent(this.$.shipAddress.value):"")
                    .param("expressId",!this.takeBySelf?this.expressValue:"")
                    .param("customerRemarks",this.$.customerRemarks.value)
                    .param("takeBySelf",this.takeBySelf)
                    .setBody(products)
                    .callback(function(e){
                        if(typeof(successCallback)=="function"){
                            successCallback.call(this,e.detail);
                        }
                        dom.$.checkoutForm.dispatchEvent(new CustomEvent('iron-form-response', {
                            composed: true,
                            detail: {
                                response: {
                                    success: 1,
                                    successMessage: '您的订单将在付款完成后生效'
                                }
                            }
                        }));
                    },function(e){
                        dom.$.checkoutForm.dispatchEvent(new CustomEvent('iron-form-response', {
                            composed: true,
                            detail: {
                                response: {
                                    success:0,
                                    error: 1,
                                    errorMessage: e.detail.message
                                }
                            }
                        }));
                        dom._reset();
                    })
                    .post();
                    dom._cache("checkout.area",JSON.stringify(this.area));
                    dom._cache("checkout.pathArray",JSON.stringify(this.$.areaSelector.pathArray));
                    dom._cache("checkout.areaPath",this.$.areaSelector.path);
                    dom._cache("checkout.address",this.$.shipAddress.value);
                    dom._cache("checkout.telephone",this.$.telephone.value);
                    dom._cache("checkout.realname",this.$.realname.value);
                    dom._cache("checkout.takeBySelf",this.takeBySelf?"true":"false");
                }
            }
            _submitByPlugin(e){
                let dom = this;
                if(!e.model.plugin.config.point["shopping-checkout"]){
                    this.$.msg._error("此插件未配置订单创建接口，暂时无法使用");
                }else{
                   this._submit(e,function(trade){
                        dom.$.xhr_open_page.setBody({page:app.httpHost+"/"+e.model.plugin.id+".pl/"+e.model.plugin.config.point["shopping-checkout"]+"?trade_id="+trade.id}).callback(function(res){
                            
                        }).post();
                       //dom.$.xhr_open_page.setBody({page:"https://dev.b2wx.com/haigou.pl/"}).post();
                    });
                }
            }
            _submitByPayment(e){
                let dom = this;
                this._submit(e,function(trade){
                    dom.$.payment.commit(e);
                });
            }

            /**
             * Sets the valid state and updates the location.
             */
            _pushState(state) {
                this._validState = state;
                this.set('route.path', state);
               
                
            }

            /**
             * Checks that the `:state` subroute is correct. That is, the state has been pushed
             * after receiving response from the server. e.g. Users can only go to `/checkout/success`
             * if the server responsed with a success message.
             */
            _updateState(active, routeData) {
                
                if (active && routeData) {
                    let state = routeData.state;
                    if (this._validState === state) {
                        this.state = state;
                        this._validState = '';
                        return;
                    }
                }
                this.state = 'init';
            }
            _updatePromotion(){
                let quantity = 0;
                if(this.single){
                    quantity +=this.singleItem.quantity;
                }else{
                    this.cart.forEach(function(entry){
                        quantity +=entry.quantity;
                    });
                }
                
                let dom = this;
                this.$.xhr_discount_list_filter.param("app_id",app.appId).param("quantity",quantity).param("money",this.total).callback(function(e){
                    let discounts = e.detail.result;
                    let selectedDiscount = null;
                    let maxRate = 0;
                    console.log(discounts);
                    discounts.forEach(function(discount){
                        if(discount.rate>maxRate){
                            maxRate = discount.rate;
                            selectedDiscount = discount;
                        }
                    });
                    dom.discount = selectedDiscount;
                    dom._flushPayAmount();
                }).get();
                
                this.$.xhr_my_coupon_available.callback(function(e){
                    let coupons = e.detail;
                    let selectedCouponRecord = null;
                    let maxMoney = 0;
                    coupons.forEach(function(record){
                        let coupon = JSON.parse(record.couponSnaphot);
                        record.coupon = coupon;
                        if((coupon.terms=="order-money"&&dom.total>=coupon.money)||(coupon.terms=="product-quantity"&&quantity>=coupon.quantity)&&coupon.money>maxMoney){
                            maxMoney = coupon.money;
                            selectedCouponRecord = record;
                        }
                    });
                    dom.couponRecord = selectedCouponRecord;
                    dom._flushPayAmount();
                }).get();
            }
            /**
             * Sets the initial state.
             */
            _reset() {
                this._updatePromotion();
                this._flushPayAmount();
                let form = this.$.checkoutForm;
                this._setWaiting(false);
                //form.reset();

                let nativeForm = form._form;
                if (!nativeForm) {
                    return;
                }

                // Remove the `aria-invalid` attribute from the form inputs.
                for (let el, i = 0; el = nativeForm.elements[i], i < nativeForm.elements.length; i++) {
                    el.removeAttribute('aria-invalid');
                }
            }

            /**
             * Validates the form's inputs and adds the `aria-invalid` attribute to the inputs
             * that don't match the pattern specified in the markup.
             */
            _validateForm() {
                if(this.takeBySelf){
                   return true;
                }
                let form = this.$.checkoutForm;
                let firstInvalid = false;
                let nativeForm = form._form;

                for (let el, i = 0; el = nativeForm.elements[i], i < nativeForm.elements.length; i++) {
                    if (el.checkValidity()) {
                        el.removeAttribute('aria-invalid');
                    } else {
                        if (!firstInvalid) {
                            // announce error message
                            if (el.nextElementSibling) {
                                this.dispatchEvent(new CustomEvent('announce', {
                                    bubbles: true,
                                    composed: true,
                                    detail: el.nextElementSibling.getAttribute('error-message')
                                }));
                            }
                            if (el.scrollIntoViewIfNeeded) {
                                // safari, chrome
                                el.scrollIntoViewIfNeeded();
                            } else {
                                // firefox, edge, ie
                                el.scrollIntoView(false);
                            }
                            el.focus();
                            firstInvalid = true;
                        }
                        el.setAttribute('aria-invalid', 'true');
                    }
                }
                if(!firstInvalid){
                    if(!this.area){
                       this.$.msg._error("请选择配送地区");
                        return false;
                    }else if(!this.expressAvailable){
                        this.$.msg._error("本店物流无法送达指定地区");
                        return false;
                    }else if(this._isEmpty(this.expressValue)){
                        this.$.msg._error("请选择快递");
                        return false;
                    }
                }
                return !firstInvalid;
            }

            /**
             * Adds the cart data to the payload that will be sent to the server
             * and updates the UI to reflect the waiting state.
             */
            _willSendRequest(e) {
                let form = e.target;
                let body = form.ajax && form.ajax.body;

                this._setWaiting(true);

                if (!body) {
                    return;
                }
                // Populate the request body where `cartItemsId[i]` is the ID and `cartItemsQuantity[i]`
                // is the quantity for some item `i`.
                body.cartItemsId = [];
                body.cartItemsQuantity = [];

                
                if(this.single){
                    body.cartItemsId.push(this.singleItem.item.name);
                    body.cartItemsQuantity.push(this.singleItem.quantity);
                }else{
                   this.cart.forEach((cartItem) => {
                        body.cartItemsId.push(cartItem.item.name);
                        body.cartItemsQuantity.push(cartItem.quantity);
                    }); 
                }
                
            }

            /**
             * Handles the response from the server by checking the response status
             * and transitioning to the success or error UI.
             */
            _didReceiveResponse(e) {
                let response = e.detail.response;

                this.response = response;
                this._setWaiting(true);

                if (response.success) {
                    this._pushState('success');
                    this._reset();
                    if(!this.single){
                        this.dispatchEvent(new CustomEvent('clear-cart', {
                            bubbles: true,
                            composed: true
                        }));
                    }
                    
                } else {
                    this._pushState('error');
                }
            }

            _computeHasItem(single,cartLength) {
                return single||cartLength > 0;
            }

            _formatPrice(total) {
                return isNaN(total) ? '' : '￥' + total.toFixed(2);
            }

            _getEntryTotal(entry) {
                return this._formatPrice(entry.quantity * entry.item.price);
            }

            _visibleChanged(visible) {
                app.$.customerService.className = visible?"action":"";
                if (!visible) {
                    return;
                }
                this.paymented = false;
                this.single = this._param("single")?true:false;
                this.singleItem = app.singleItem;
                this.$.xhr_plugin_list_by_category.param("plugin_category","sale").param("app_id",app.appId).get();
                // Reset the UI states
                this._reset();
                // Notify the page's title
                this.dispatchEvent(new CustomEvent('change-section', {
                    bubbles: true,
                    composed: true,
                    detail: {
                        title: 'Checkout'
                    }
                }));
                this.$.nav.select("");
                this.$.nav.select(Number(this.takeBySelf));
            }
            _skuDisplay(sku){
                let arr = new Array();
                for(let n in sku){
                    if(n!="id"){
                       arr.push(sku[n]);
                    }
                }
                return arr.join("/");
            }
        }

        customElements.define(ShopCheckout.is, ShopCheckout);

    </script>

</dom-module>
